#include "iobot.h"

void iobot_put_char(iobot_t *bot, unsigned char c)
{
	unsigned int position_equation = (bot->csr_y * bot->textwidth) + bot->csr_x;
	if(position_equation >= 12288)
		return;

	if(!bot->dirty)	
	{//the iobot is clean, setup a new dirty area
		bot->dirty_x = bot->csr_x + 1;
		bot->dirty_y = bot->csr_y + 1 - bot->scroll;
		bot->dirty_width = 2;
		bot->dirty_height = 2;
	}
	else
	{//the iobot is alredy dirty, just expand the dirty area
		//if the character just written is to the left of the dirty area...
		if(bot->csr_x + 1 < bot->dirty_x)
		{//expand the dirty area back to encompas the new character
			bot->dirty_x = bot->csr_x + 1;
		}
		else
		//if the character just written is beyond the right edge of the dirty area
		if(bot->csr_x + 1 >= bot->dirty_x + bot->dirty_width)
		{//expand the dirty area to the right to encompas it
			bot->dirty_width = (bot->csr_x + 1) - bot->dirty_x + 1;
		}
		else
		//if the character just written is above the dirty area...
		if(bot->csr_y + 1 < bot->dirty_y)
		{//expand the dirty area up to encompas the new character
			bot->dirty_y = bot->csr_y + 1;
		}
		else
		//if the character just written is below the bottom edge of the dirty area
		if(bot->csr_y + 1 >= bot->dirty_y + bot->dirty_height)
		{//expand the dirty area down to encompas it
			bot->dirty_height = (bot->csr_y + 1) - bot->dirty_y + 1;
		}
	}

    if(c == '\b')
    {
		//handling a backspace requires a little more logic in a seperate function.
    	iobot_backspace(bot);
    }
    /* Handles a tab by incrementing the cursor's x, but only
    *  to a point that will make it divisible by 8 */
    else if(c == '\t')
    {
        bot->csr_x = (bot->csr_x + 8) & ~(8 - 1);
    }
    /* Handles a 'Carriage Return', which simply brings the
    *  cursor back to the margin */
    else if(c == '\r')
    {
        bot->csr_x = 0;
    }
    else if(c == '\n')
    {
        bot->csr_x = 0;
        bot->csr_y++;
    }
	else if(c == 140)//up arrow
	{
		if(bot->csr_y > 0)
		{
			bot->csr_y--;
		}
	}
	else if(c == 141)//right arrow
	{
		if(bot->csr_x < bot->textwidth)
		{
			bot->csr_x++;
		}
		else
		{
			if(bot->csr_y < bot->textheight)
			{
				bot->csr_y++;
				bot->csr_x = 0;
			}
		}
	}
	else if(c == 142)//down arrow
	{
		if(bot->csr_y < bot->textheight)
		{
			bot->csr_y++;
		}
	}
	else if(c == 143)//left arrow
	{
		if(bot->csr_x > 0)
		{
			bot->csr_x--;
		}
		else
		{
			if(bot->csr_y > 0)
			{
				bot->csr_y--;
				bot->csr_x = bot->textwidth - 1;
			}
		}
	} 
    /* Any character greater than and including a space, is a
    *  printable character. The equation for finding the index
    *  in a linear chunk of memory can be represented by:
    *  Index = [(y * width) + x] */
    else if(c >= ' ')
    {
	  		bot->botout[position_equation] = c;
     		bot->csr_x++;
    }
	 else
	 {//the character is unprintable
			bot->botout[position_equation] = 249;//a centered dot
			bot->csr_x++;
	 }

    /* If the cursor has reached the edge of the screen's width, we
    *  insert a new line in there */
    if(bot->csr_x >= bot->textwidth)
    {
        bot->csr_x = 0;
        bot->csr_y++;
    }
	
	if(bot->csr_y >= bot->scroll + bot->textheight)
	{
		iobot_scroll(bot, 2);
	}
	bot->dirty = 1;
}
